class Flyweight(object):
    def __init__(self, shared_state):
        self._shared_state = shared_state

    def operation(self, unique_state):
        s = self._shared_state.copy()
        s.update(unique_state)
        return s


class FlyweightFactory(object):
    _flyweights = {}

    @staticmethod
    def get_flyweight(shared_state):
        key = tuple(shared_state.items())
        if key not in FlyweightFactory._flyweights:
            FlyweightFactory._flyweights[key] = Flyweight(shared_state)
        return FlyweightFactory._flyweights[key]


def main():
    factory = FlyweightFactory()

    flyweight1 = factory.get_flyweight({"color": "red"})
    print(flyweight1.operation({"shape": "circle"}))

    flyweight2 = factory.get_flyweight({"color": "blue"})
    print(flyweight2.operation({"shape": "square"}))

    flyweight3 = factory.get_flyweight({"color": "red"})
    print(flyweight3.operation({"shape": "triangle"}))


if __name__ == '__main__':
    main()

'''
{'color': 'red', 'shape': 'circle'}
{'color': 'blue', 'shape': 'square'}
{'color': 'red', 'shape': 'triangle'}
'''
